package com.antwork.common.web.jsp;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

public class BreadcrumbTag extends AbstractTag {
	private static final long serialVersionUID = 188258662225279717L;
	private static HashMap<String, BreadcrumbConfig> configMap = new HashMap();
	private String name;
	private String contextPath;

	public void setName(String name) {
		this.name = name;
	}

	public int doStartTag() throws JspException {
		Tag tag = getParent();
		String curTabType = "";
		String tabKeepStr = "";
		if (tag instanceof TabTag) {
			TabTag tabTag = (TabTag) tag;
			curTabType = tabTag.getCurTabType();
			tabKeepStr = tabTag.getTabKeepStr();
		}

		HttpServletRequest request = (HttpServletRequest) this.pageContext
				.getRequest();
		this.contextPath = request.getContextPath();
		String uri = (String) request.getAttribute("uri");
		String b = (String) request.getAttribute("b");
		b = (b == null) ? "" : b;
		BreadcrumbConfig config = (BreadcrumbConfig) configMap.get(this.name);
		if (config == null) {
			try {
				config = loadConfig();
			} catch (Exception e) {
				throw new JspException(e);
			}
			configMap.put(this.name, config);
		}
		if (config == null) {
			return 6;
		}
		String baseURI = config.getUri();
		String simpleURI = getOriginalAndTabURI(uri, baseURI, curTabType,
				tabKeepStr);
		String[] breadcrumbType = config.getBreadcrumbType();
		String[] displayName = config.getDisplayName();
		boolean isMatching = false;
		if (!b.equals("")) {
			for (int i = 0; i < breadcrumbType.length; ++i) {
				if (b.equals(breadcrumbType[i])) {
					isMatching = true;
				}
			}
			if (!isMatching) {
				b = "";
			}
		}
		StringBuffer htmlStr = new StringBuffer("<div class=\"tabbable\">");
		htmlStr.append("<ul class=\"breadcrumb\">");
		for (int i = 0; i < breadcrumbType.length; ++i) {
			if ((b.equals("")) && (i == 0)) {
				htmlStr.append("<li class=\"active\">" + displayName[i]);
			} else if (b.equals(breadcrumbType[i])) {
				htmlStr.append("<li class=\"active\">" + displayName[i]);
			} else {
				String[] keep = config.getKeep();
				String keepStr = "";
				if (keep != null) {
					for (int j = 0; j < keep.length; ++j) {
						keepStr = keepStr + "&"
								+ getKeepParameterAndValue(uri, keep[j]);
					}
					if (!keepStr.equals(""))
						keepStr = keepStr.substring(1);
				}
				String url;
				if (i == 0) {
					if (keepStr.equals(""))
						url = simpleURI;
					else
						url = simpleURI + getNextSeperator(simpleURI) + keepStr;
				} else {
					if (keepStr.equals(""))
						url = simpleURI + getNextSeperator(simpleURI) + "b="
								+ breadcrumbType[i];
					else {
						url = simpleURI + getNextSeperator(simpleURI) + "b="
								+ breadcrumbType[i] + "&" + keepStr;
					}
				}

				htmlStr.append("<li><a href=\"" + url + "\">" + displayName[i]
						+ "</a>");
			}

			if (i == breadcrumbType.length - 1)
				htmlStr.append("</li>");
			else {
				htmlStr.append(" <span class=\"divider\">|</span></li> ");
			}
		}
		htmlStr.append("</ul>");
		htmlStr.append("</div>");
		JspWriter writer = this.pageContext.getOut();
		try {
			writer.write(htmlStr.toString());
		} catch (IOException e) {
			throw new JspException(e);
		}

		return 6;
	}

	private BreadcrumbConfig loadConfig() throws Exception {
		String configName = "/page-" + this.name + ".properties";
		Properties prop = new Properties();
		try {
			InputStream is = BreadcrumbConfig.class
					.getResourceAsStream(configName);

			prop.load(is);
		} catch (Throwable e) {
			throw new RuntimeException("table-config file cannot be load: "
					+ configName);
		}
		try {
			// Properties prop = null;
			BreadcrumbConfig config = new BreadcrumbConfig();
			String categoryStr = (String) prop.get("breadcrumb.category");
			if (categoryStr != null) {
				String[] cs = categoryStr.split(";");
				String[] breadcrumbType = new String[cs.length];
				String[] displayName = new String[cs.length];
				for (int i = 0; i < cs.length; ++i) {
					String[] c = cs[i].split("\\|");
					breadcrumbType[i] = c[0];
					displayName[i] = c[1];
				}
				config.setBreadcrumbType(breadcrumbType);
				config.setDisplayName(displayName);
				String uri = (String) prop.get("breadcrumb.uri");
				config.setUri(uri);
			}
			String keepStr = (String) prop.get("breadcrumb.keep");
			if (keepStr != null) {
				String[] keep = keepStr.split(";");
				config.setKeep(keep);
			}
			return config;
		} catch (Exception e) {
			throw new Exception("Parse " + configName + " error! "
					+ e.getMessage());
		}
	}

	private String getOriginalAndTabURI(String uri, String baseURI,
			String curTabType, String tabKeepStr) {
		uri = uri.replaceAll("#", "");
		if (uri.indexOf("?") != -1) {
			if (baseURI != null)
				uri = this.contextPath + baseURI;
			else {
				uri = uri.substring(0, uri.indexOf("?"));
			}
		} else if (baseURI != null) {
			uri = this.contextPath + baseURI;
		}

		if (!curTabType.equals("")) {
			uri = uri + "?t=" + curTabType;
		}
		if (uri.indexOf("?") != -1) {
			if (!tabKeepStr.equals("")) {
				uri = uri + "&" + tabKeepStr;
			}
		} else if (!tabKeepStr.equals("")) {
			uri = uri + "?" + tabKeepStr;
		}

		return uri;
	}

	private String getKeepParameterAndValue(String uri, String param) {
		int index = uri.indexOf(param);
		if (index != -1) {
			String str = uri.substring(index, uri.length());
			String[] s = str.split("&");
			return s[0];
		}
		return "";
	}
}